<?php

class ServiceResponse extends AbstractResponse
{
	const OUTPUT_SERVICE = 0;
	const OUTPUT_BUFFER  = 1;

	private static $value    = array();
	private static $stream   = null;
	private static $instance = null;
	private static $obInit   = false;

	public static $streamMode = self::OUTPUT_SERVICE;
	public static $streamName = "stream";

	private static function init()
	{
		if ( !self::$obInit )
		{
			self::$stream = "";

			ob_start();

			self::$obInit = true;
		}
	}

	public function write($data)
	{
		if ( self::$streamMode == self::OUTPUT_BUFFER ) {
			self::init();

			self::$stream .= $data;
		}
		else {
			echo $data;
		}
	}

	public function writeFromFile($filename)
	{
		if ( !file_exists($filename) )
			return;

		if ( self::$streamMode == self::OUTPUT_BUFFER )
			self::init();

		include( $filename );

		if ( self::$streamMode == self::OUTPUT_BUFFER ) {
			self::$stream .= ob_get_contents();
			ob_clean();
		}
	}

	public static function streamSave($name, $clean = false)
	{
		if ( !$name || (self::$streamMode != self::OUTPUT_BUFFER) )
			return;

		self::init();
		self::$stream .= ob_get_contents();

		$backup  = self::getValue($name);

		if ( isset($backup) ) {
			$backup  = base64_decode( $backup );
		}
		else {
			$backup = "";
		}

		self::setValue($name, base64_encode( $backup . self::$stream ) );

		if ( $clean ) {
			self::$stream = "";
			ob_clean();
		}
	}

	public static function flush($name)
	{
		self::streamSave($name, true);
	}

	public static function close()
	{
		if ( self::$streamMode == self::OUTPUT_BUFFER ) {
			self::flush( self::$streamName );
		}

		$json = CoreLib::json_encode(self::$value);

		$response = $json;

		return( $response );
	}

	public static function getContext()
	{
		$context = new Context();

		foreach(array_keys(self::$value) as $item ) {
			$context->$item( self::$value[$item] );
		}

		Context::merge(Session::$context, $context);

		return($context);
	}

	public static function setValue($valueName, $data)
	{
		self::$value[$valueName] = $data;

		return(true);
	}

	public static function setError($errSpec)
	{

		if ( method_exists($errSpec, "toJSON") ) {
			$publicErr = $errSpec->toJSON();
		}
		else {
			$custom = new UnhandledException(
				$errSpec->name, $errSpec->getMessage(),
				$errSpec->getCode(),
				$errSpec->source
			);

			$publicErr = $custom->toJSON();
		}

		self::setValue("error", base64_encode($publicErr) );

		return(true);
	}

	public static function getValue($valueName)
	{
		return(self::$value[$valueName]);
	}

	public static function getInstance()
	{
		if ( isset( self::$instance ) )
			return( self::$instance );

		$response = new Response();
		self::$instance = $response;

		return( $response );
	}

	public function raiseError( $errorClass, $message = "", $source = "" )
	{
		$error = new $errorClass( $message, 0, $source );

		self::setError($error);

		throw $error;
	}
}

?>
